package com.moyoutian.leetcode.difficult;

import java.util.ArrayList;
import java.util.List;

/**
 * 68. 文本左右对齐
 * 给定一个单词数组和一个长度 maxWidth，重新排版单词，使其成为每行恰好有 maxWidth 个字符，且左右两端对齐的文本。
 * <p>
 * 你应该使用“贪心算法”来放置给定的单词；也就是说，尽可能多地往每行中放置单词。必要时可用空格 ' ' 填充，使得每行恰好有 maxWidth 个字符。
 * <p>
 * 要求尽可能均匀分配单词间的空格数量。如果某一行单词间的空格不能均匀分配，则左侧放置的空格数要多于右侧的空格数。
 * <p>
 * 文本的最后一行应为左对齐，且单词之间不插入额外的空格。
 * <p>
 * 说明:
 * <p>
 * 单词是指由非空格字符组成的字符序列。
 * 每个单词的长度大于 0，小于等于 maxWidth。
 * 输入单词数组 words 至少包含一个单词。
 * 示例:
 * <p>
 * 输入:
 * words = ["This", "is", "an", "example", "of", "text", "justification."]
 * maxWidth = 16
 * 输出:
 * [
 * "This    is    an",
 * "example  of text",
 * "justification.  "
 * ]
 * 示例 2:
 * <p>
 * 输入:
 * words = ["What","must","be","acknowledgment","shall","be"]
 * maxWidth = 16
 * 输出:
 * [
 * "What   must   be",
 * "acknowledgment  ",
 * "shall be        "
 * ]
 * 解释: 注意最后一行的格式应为 "shall be    " 而不是 "shall     be",
 * 因为最后一行应为左对齐，而不是左右两端对齐。
 * 第二行同样为左对齐，这是因为这行只包含一个单词。
 * 示例 3:
 * <p>
 * 输入:
 * words = ["Science","is","what","we","understand","well","enough","to","explain",
 * "to","a","computer.","Art","is","everything","else","we","do"]
 * maxWidth = 20
 * 输出:
 * [
 * "Science  is  what we",
 * "understand      well",
 * "enough to explain to",
 * "a  computer.  Art is",
 * "everything  else  we",
 * "do                  "
 * ]
 */
public class Demo68 {

    public static void main(String[] args) {
        String[] words = {"This", "is", "an", "example", "of", "text", "justification."};
        int maxWidth = 16;
        System.out.println(fullJustify(words, maxWidth));
    }

    public static List<String> fullJustify(String[] words, int maxWidth) {
        if (words == null || words.length == 0) {
            return null;
        }
        List<String> list = new ArrayList<>();
        //
        int currentLength = 0;
        //当前拼接单词的数量
        int wordCount = 0;
        for (int i = 0; i < words.length; i++) {
            if (currentLength == 0) {
                currentLength += words[i].length();
                wordCount++;
            } else if (currentLength + words[i].length() + 1 <= maxWidth) {
                currentLength += words[i].length() + 1;
                wordCount++;
            } else {
                list.add(getString(words, i - wordCount, wordCount, maxWidth, currentLength, false));
                currentLength = words[i].length();
                wordCount = 1;
            }
        }
        if (currentLength != 0) {
            list.add(getString(words, words.length - wordCount, wordCount, maxWidth, currentLength, true));
        }
        return list;
    }


    /**
     * @param beginIndex    开始下标
     * @param wordCount     单词数量
     * @param maxWidth      长度限制
     * @param currentLength 当前
     * @param tailFlag      是否是结尾的标志
     * @return 构建一个字符串
     */
    public static String getString(String[] words, int beginIndex, int wordCount, int maxWidth, int currentLength, boolean tailFlag) {
        if (wordCount > 0) {
            //一个单次和结尾时候单词间隔只需要一个空格
            if (wordCount == 1 || tailFlag) {
                StringBuilder stringBuffer = new StringBuilder();
                for (int i = beginIndex; i <= beginIndex + wordCount - 1; i++) {
                    //不是开始就先加空格
                    if (i != beginIndex) {
                        stringBuffer.append(" ");
                    }
                    stringBuffer.append(words[i]);
                }
                //缺少空格的数量
                int spaceCount = maxWidth - currentLength;
                for (int i1 = 0; i1 < spaceCount; i1++) {
                    stringBuffer.append(" ");
                }
                return stringBuffer.toString();
            } else {
                //缺少空格的数量
                int spaceCount = maxWidth - currentLength;
                //有几个位置填写空格
                int spaceI = wordCount - 1;
                //每个都必须填写空格的个数+1，+1是原始计算长度时候加上的
                int t = spaceCount / spaceI;
                //前面多一个空格的数量
                int addOneLen = spaceCount % spaceI;
                StringBuilder stringBuffer = new StringBuilder();
                for (int i = beginIndex; i <= beginIndex + wordCount - 1; i++) {
                    //不是开始就先加空格
                    if (i != beginIndex) {
                        int all = t;
                        if (i - beginIndex <= addOneLen) {
                            all = t + 1;
                        }
                        for (int i1 = 0; i1 <= all; i1++) {
                            stringBuffer.append(" ");
                        }
                    }
                    stringBuffer.append(words[i]);
                }
                return stringBuffer.toString();
            }
        }
        return "";
    }


}
